package com.elsa.gateway.filter;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import com.elsa.common.entity.ElsaResponse;
import com.elsa.common.utils.ElsaUtil;
import com.netflix.zuul.context.RequestContext;

/**
 * @projectName：elsa-gateway
 * @typeName：ElsaGatewayErrorFilter
 * @author：cos
 * @date：2021年5月11日 @version
 * @desc：自定义Zuul异常处理过滤器
 */
@Component
public class ElsaGatewayErrorFilter extends SendErrorFilter {
	private Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public Object run() {
		try {
			ElsaResponse elsaResponse = new ElsaResponse();
			RequestContext ctx = RequestContext.getCurrentContext();
			String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);

			ExceptionHolder exception = findZuulException(ctx.getThrowable());
			String errorCause = exception.getErrorCause();
			Throwable throwable = exception.getThrowable();
			String message = throwable.getMessage();
			message = StringUtils.isBlank(message) ? errorCause : message;
			elsaResponse = resolveExceptionMessage(message, serviceId, elsaResponse);

			HttpServletResponse response = ctx.getResponse();
			ElsaUtil.makeResponse(response, MediaType.APPLICATION_JSON_UTF8_VALUE,
					HttpServletResponse.SC_INTERNAL_SERVER_ERROR, elsaResponse);
			log.error("Zull sendError：{}", elsaResponse.getMessage());
		} catch (Exception ex) {
			log.error("Zuul sendError", ex);
			ReflectionUtils.rethrowRuntimeException(ex);
		}
		return null;
	}

	private ElsaResponse resolveExceptionMessage(String message, String serviceId, ElsaResponse elsaResponse) {
		if (StringUtils.containsIgnoreCase(message, "time out")) {
			return elsaResponse.message("请求" + serviceId + "服务超时");
		}
		if (StringUtils.containsIgnoreCase(message, "forwarding error")) {
			return elsaResponse.message(serviceId + "服务不可用");
		}
		return elsaResponse.message("Zuul请求" + serviceId + "服务异常");
	}
}
